package ycl.common.result;

import com.alibaba.fastjson2.JSON;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;

import java.io.Serializable;

/**
 * 统一返回对象
 *
 * @author YCL
 * @date 2021-06-06 09:19:45
 */
@Data
@Accessors(chain = true)
public class Result<T> implements Serializable {


	private static final long serialVersionUID = 2047317951422915349L;


	@ApiModelProperty(value = "状态码", position = 1)
	private int code;
	@ApiModelProperty(value = "是否成功", position = 2)
	private boolean success;
	@ApiModelProperty(value = "消息内容", position = 3)
	private String msg;
	@ApiModelProperty(value = "返回数据", position = 11)
	private T data;

	private Result() {
	}

	//自定义返回 --------------------

	public static <T> Result<T> custom(BaseR r, T data) {
		return custom(r.getCode(), r.getMsg(), data, r.getIsSuccess());
	}

	//成功返回 --------------------

	public static <T> Result<T> success() {
		return success(REnum.USED_OK, null);
	}

	public static <T> Result<T> success(T data) {
		return success(REnum.USED_OK, data);
	}

	public static <T> Result<T> success(REnum enums, T data) {
		return custom(enums.code, enums.msg, data, true);
	}


	//失败返回 --------------------

	public static <T> Result<T> fail() {
		return fail(REnum.USED_SERVER_ERROR);
	}

	public static <T> Result<T> fail(T data) {
		return fail(REnum.USED_SERVER_ERROR, data);
	}

	public static <T> Result<T> fail(String msg) {
		return fail(REnum.USED_SERVER_ERROR.code, msg, null);
	}

	public static <T> Result<T> fail(String msg, T data) {
		return fail(REnum.USED_SERVER_ERROR.code, msg, data);
	}


	public static <T> Result<T> fail(REnum enums) {
		return fail(enums.code, enums.msg, null);
	}

	public static <T> Result<T> fail(REnum enums, T data) {
		return fail(enums.code, enums.msg, data);
	}

	private static <T> Result<T> fail(int code, String msg, T data) {
		return custom(code, msg, data, false);
	}

	private static <T> Result<T> custom(int code, String msg, T data, boolean success) {
		Result<T> result = new Result<>();
		result.setCode(code)
				.setMsg(msg)
				.setData(data)
				.setSuccess(success);
		return result;
	}

	public static <T> Result<T> error(int code, String msg) {
		return fail(code, msg, null);
	}

	public static <T> Result<T> defaultError(Class<T> clazz) {
		return fail(REnum.USED_SERVER_ERROR, null);
	}

	public static <T> Result<T> badRequest(String msg) {
		return fail(REnum.BAD_REQUEST);
	}


	@Override
	public String toString() {
		return JSON.toJSONString(this);
	}
}
